package com.lsyw.intergrate.common.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtil {

    public static final String DATE_DIVISION = "-";

    public static final String DATE_PATTON_DEFAULT_HOUR = "yyyy-MM-dd HH";
    public static final String DATE_PATTON_DEFAULT = "yyyy-MM-dd";
    public static final String DATE_PATTON_DEFAULT_MONTH = "yyyy-MM";
    public static final String DATE_PATTON_DEFAULT_YEAR = "yyyy";
    public static final String DATA_PATTON_YYYYMMDD = "yyyyMMdd";
    public static final String DATA_PATTON_YYYYMM = "yyyyMM";
    public static final String DATA_PATTON_DD = "yyyyMMdd";
    public static final String TIME_PATTON_DEFAULT = "yyyy-MM-dd HH:mm:ss";
    public static final String TIME_PATTON_HHMMSS = "HH:mm:ss";
    public static final String TIME_PATTON_CRON = "ss mm HH dd MM ? yyyy";

    public static final int ONE_SECOND = 1000;
    public static final int ONE_MINUTE = 60 * ONE_SECOND;
    public static final int ONE_HOUR = 60 * ONE_MINUTE;
    public static final long ONE_DAY = 24 * ONE_HOUR;

    /** 毫秒 */
    public static final long MS = 1;
    /** 每秒钟的毫秒数 */
    public static final long SECOND_MS = MS * 1000;
    /** 每分钟的毫秒数 */
    public static final long MINUTE_MS = SECOND_MS * 60;
    /** 每小时的毫秒数 */
    public static final long HOUR_MS = MINUTE_MS * 60;
    /** 每天的毫秒数 */
    public static final long DAY_MS = HOUR_MS * 24;

    /**
     * Return the current date
     *
     * @return － DATE<br>
     */
    public static Date getCurrentDate() {
        Calendar cal = Calendar.getInstance();
        Date currDate = cal.getTime();

        return currDate;
    }

    /**
     * Return the current date string
     *
     * @return － 产生的日期字符串<br>
     */
    public static String getCurrentDateStr() {
        Calendar cal = Calendar.getInstance();
        Date currDate = cal.getTime();

        return format(currDate);
    }


    /**
     * Return the current date in the specified format
     *
     * @param strFormat
     * @return
     */
    public static String getCurrentDateStr(String strFormat) {
        Calendar cal = Calendar.getInstance();
        Date currDate = cal.getTime();

        return format(currDate, strFormat);
    }

    /**
     * Parse a string and return a date value
     *
     * @param dateValue
     * @return
     */
    public static Date parseDate(String dateValue) {
        return parseDate(DATE_PATTON_DEFAULT, dateValue);
    }

    /**
     * Parse a strign and return a datetime value
     *
     * @param dateValue
     * @return
     */
    public static Date parseDateTime(String dateValue) {
        return parseDate(TIME_PATTON_DEFAULT, dateValue);
    }

    /**
     * Parse a string and return the date value in the specified format
     *
     * @param strFormat
     * @param dateValue
     * @return
     */
    public static Date parseDate(String strFormat, String dateValue) {
        if (dateValue == null)
            return null;

        if (strFormat == null)
            strFormat = TIME_PATTON_DEFAULT;

        SimpleDateFormat dateFormat = new SimpleDateFormat(strFormat);
        Date newDate = null;

        try {
            newDate = dateFormat.parse(dateValue);
        } catch (ParseException pe) {
            newDate = null;
        }

        return newDate;
    }

    /**
     * 将Timestamp类型的日期转换为系统参数定义的格式的字符串。
     *
     * @param aTs_Datetime 需要转换的日期。
     * @return 转换后符合给定格式的日期字符串
     */
    public static String format(Date aTs_Datetime) {
        return format(aTs_Datetime, DATE_PATTON_DEFAULT);
    }

    public static String formatHour(Date aTs_Datetime) {
        return format(aTs_Datetime, DATE_PATTON_DEFAULT_HOUR);
    }

    public static String formatMonth(Date aTs_Datetime) {
        return format(aTs_Datetime, DATE_PATTON_DEFAULT_MONTH);
    }

    public static String formatYear(Date aTs_Datetime) {
        return format(aTs_Datetime, DATE_PATTON_DEFAULT_YEAR);
    }

    /**
     * 将Timestamp类型的日期转换为系统参数定义的格式的字符串。
     *
     * @param aTs_Datetime 需要转换的日期。
     * @return 转换后符合给定格式的日期字符串
     */
    public static String formatTime(Date aTs_Datetime) {
        return format(aTs_Datetime, TIME_PATTON_DEFAULT);
    }

    /**
     * 将Date类型的日期转换为系统参数定义的格式的字符串。
     *
     * @param aTs_Datetime
     * @param as_Pattern
     * @return
     */
    public static String format(Date aTs_Datetime, String as_Pattern) {
        if (aTs_Datetime == null || as_Pattern == null)
            return null;

        SimpleDateFormat dateFromat = new SimpleDateFormat();
        dateFromat.applyPattern(as_Pattern);

        return dateFromat.format(aTs_Datetime);
    }

    /**
     * @param aTs_Datetime
     * @param as_Format
     * @return
     */
    public static String formatTime(Date aTs_Datetime, String as_Format) {
        if (aTs_Datetime == null || as_Format == null)
            return null;

        SimpleDateFormat dateFromat = new SimpleDateFormat();
        dateFromat.applyPattern(as_Format);

        return dateFromat.format(aTs_Datetime);
    }

    public static String getFormatTime(Date dateTime) {
        return formatTime(dateTime, TIME_PATTON_HHMMSS);
    }

    /**
     * @param aTs_Datetime
     * @param as_Pattern
     * @return
     */
    public static String format(Timestamp aTs_Datetime, String as_Pattern) {
        if (aTs_Datetime == null || as_Pattern == null)
            return null;

        SimpleDateFormat dateFromat = new SimpleDateFormat();
        dateFromat.applyPattern(as_Pattern);

        return dateFromat.format(aTs_Datetime);
    }

    /**
     * 取得指定日期N天后的日期
     *
     * @param date
     * @param days
     * @return
     */
    public static Date addDays(Date date, int days) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        cal.add(Calendar.DAY_OF_MONTH, days);

        return cal.getTime();
    }

    /**
     * 计算两个日期之间的天数（包含头尾）
     *
     * @param minDate 较小的日期
     * @param maxDate 较大的日期
     * @return
     */
    public static int daysBetween(Date minDate, Date maxDate) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            minDate = dateFormat.parse(dateFormat.format(minDate));
            maxDate = dateFormat.parse(dateFormat.format(maxDate));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(minDate);
        long minTime = calendar.getTimeInMillis();
        calendar.setTime(maxDate);
        long maxTime = calendar.getTimeInMillis();
        long between_days = (maxTime - minTime) / (1000 * 3600 * 24) + 1;
        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 计算两个日期之间的小时数
     *
     * @param minDate 较小的日期
     * @param maxDate 较大的日期
     * @return
     */
    public static int hoursBetween(Date minDate, Date maxDate) {
        long diff = maxDate.getTime() - minDate.getTime();
        long hours = diff / 60 / 60 / 1000;
        return Integer.parseInt(Long.toString(hours));
    }
    /**
     * 计算两个日期之间的分钟数
     *
     * @param minDate 较小的日期
     * @param maxDate 较大的日期
     * @return
     */
    public static int minBetween(Date minDate, Date maxDate) {
        long diff = maxDate.getTime() - minDate.getTime();
        long min = diff / 60 / 1000;
        return Integer.parseInt(Long.toString(min));
    }
    /**
     * 计算两个日期之间的秒数
     *
     * @param minDate 较小的日期
     * @param maxDate 较大的日期
     * @return
     */
    public static int secBetween(Date minDate, Date maxDate) {
        long diff = maxDate.getTime() - minDate.getTime();
        long sec = diff / 1000;
        return Integer.parseInt(Long.toString(sec));
    }

    /**
     * 计算当前日期相对于"1977-12-01"的天数
     *
     * @param date
     * @return
     */
    public static long getRelativeDays(Date date) {
        Date relativeDate = DateUtil.parseDate("yyyy-MM-dd", "1977-12-01");

        return DateUtil.daysBetween(relativeDate, date);
    }

    public static Date getDateBeforTwelveMonth() {
        String date = "";
        Calendar cla = Calendar.getInstance();
        cla.setTime(getCurrentDate());
        int year = cla.get(Calendar.YEAR) - 1;
        int month = cla.get(Calendar.MONTH) + 1;
        if (month > 9) {
            date = String.valueOf(year) + DATE_DIVISION + String.valueOf(month) + DATE_DIVISION + "01";
        } else {
            date = String.valueOf(year) + DATE_DIVISION + "0" + String.valueOf(month) + DATE_DIVISION + "01";
        }
        Date dateBefore = parseDate(date);
        return dateBefore;
    }

    /**
     * 传入时间字符串,加一天后返回Date
     *
     * @param date 时间 格式 YYYY-MM-DD
     * @return
     */
    public static Date addDate(String date) {
        if (date == null) {
            return null;
        }

        Date tempDate = parseDate(DATE_PATTON_DEFAULT, date);
        String year = format(tempDate, "yyyy");
        String month = format(tempDate, "MM");
        String day = format(tempDate, "dd");

        GregorianCalendar calendar = new GregorianCalendar(Integer.parseInt(year), Integer.parseInt(month) - 1, Integer.parseInt(day));

        calendar.add(Calendar.DATE, 1);
        return calendar.getTime();
    }


    /**
     * 获取当天的结束时间
     *
     * @param date
     * @return
     */
    public static Date getEndTime(Date date) {
        Calendar dateEnd = Calendar.getInstance();
        dateEnd.setTime(date);
        dateEnd.set(Calendar.HOUR_OF_DAY, 23);
        dateEnd.set(Calendar.MINUTE, 59);
        dateEnd.set(Calendar.SECOND, 59);
        return dateEnd.getTime();
    }

    /**
     * 获取今天的开始时间
     *
     * @param date
     * @return
     */
    public static Date getStartTime(Date date) {
        Calendar dateStart = Calendar.getInstance();
        dateStart.setTime(date);
        dateStart.set(Calendar.HOUR_OF_DAY, 0);
        dateStart.set(Calendar.MINUTE, 0);
        dateStart.set(Calendar.SECOND, 0);
        dateStart.set(Calendar.MILLISECOND, 0);
        return dateStart.getTime();
    }


    /**
     * 得到时间所属季度
     *
     * @param date
     * @return
     */
    public static Integer getDateQuarter(Date date) {
        Integer dateMonth = getDateMonth(date);
        if (dateMonth >= 1 && dateMonth <= 3) {
            return 0;
        } else if (dateMonth > 3 && dateMonth <= 6) {
            return 1;
        } else if (dateMonth > 6 && dateMonth <= 9) {
            return 2;
        } else {
            return 3;
        }
    }

    /**
     * 获取某个日期为星期几
     *
     * @param date
     * @return String "星期*"
     */
    public static String getDayWeekOfDate(Date date) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;

        return weekDays[w];
    }

    /**
     * 获得指定时间加减参数后的日期(不计算则输入0)
     *
     * @param date 指定日期
     * @param hour 小时数，可正可负
     * @return 计算后的日期
     */
    public static Date addHour(Date date, int hour) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.HOUR, hour);//加减小时数
        return c.getTime();
    }

    /**
     * 获得指定时间加减参数后的日期(不计算则输入0)
     *
     * @param date   指定日期
     * @param minute 小时数，可正可负
     * @return 计算后的日期
     */
    public static Date addMinute(Date date, int minute) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, minute);//加减分钟数
        return c.getTime();
    }

    /**
     * 获得指定时间加减参数后的日期(不计算则输入0)
     *
     * @param date        指定日期
     * @param year        年数，可正可负
     * @param month       月数，可正可负
     * @param day         天数，可正可负
     * @param hour        小时数，可正可负
     * @param minute      分钟数，可正可负
     * @param second      秒数，可正可负
     * @param millisecond 毫秒数，可正可负
     * @return 计算后的日期
     */
    public static Date addDate(Date date, int year, int month, int day, int hour, int minute, int second, int millisecond) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR, year);//加减年数
        c.add(Calendar.MONTH, month);//加减月数
        c.add(Calendar.DATE, day);//加减天数
        c.add(Calendar.HOUR, hour);//加减小时数
        c.add(Calendar.MINUTE, minute);//加减分钟数
        c.add(Calendar.SECOND, second);//加减秒
        c.add(Calendar.MILLISECOND, millisecond);//加减毫秒数

        return c.getTime();
    }


    /**
     * 获取小时的结束时间
     *
     * @param date
     * @return
     */
    public static Date getHourEndTime(Date date) {
        Calendar dateEnd = Calendar.getInstance();
        dateEnd.setTime(date);
        dateEnd.set(Calendar.MINUTE, 59);
        dateEnd.set(Calendar.SECOND, 59);
        return dateEnd.getTime();
    }

    /**
     * 获取小时的开始时间
     *
     * @param date
     * @return
     */
    public static Date getHourStartTime(Date date) {
        Calendar dateStart = Calendar.getInstance();
        dateStart.setTime(date);
        dateStart.set(Calendar.MINUTE, 0);
        dateStart.set(Calendar.SECOND, 0);
        return dateStart.getTime();
    }

    /**
     * 得到当前时间所在年份
     *
     * @param date
     * @return
     */
    public static Integer getDateYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 得到当前时间所在月份
     *
     * @param date
     * @return
     */
    public static Integer getDateMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取该时间的小时
     *
     * @param date
     * @return
     */
    public static int getHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return calendar.get(Calendar.HOUR_OF_DAY);

    }

    /**
     * 获取该时间的分
     *
     * @param date
     * @return
     */
    public static int getMinute(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 获取该时间的秒
     *
     * @param date
     * @return
     */
    public static int getSecond(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.SECOND);
    }

    /**
     * 获取该时间的号
     *
     * @param date
     * @return
     */
    public static int getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return calendar.get(Calendar.DAY_OF_MONTH);

    }

    /**
     * 获取该时间的月
     *
     * @param date
     * @return
     */
    public static int getMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return calendar.get(Calendar.MONTH) + 1;

    }

    /**
     * 得到今天0点0时0分额date 数据
     *
     * @return
     */
    public static Date getTodayStart() {
        return parseDate(format(new Date(), "yyyy-MM-dd 00:00:00"));
    }

    /**
     * 等到两个时间的秒数差
     *
     * @param oneDate
     * @param twoDate
     * @return
     */
    public static Long getSecondBetweenTwoDate(Date oneDate, Date twoDate) {
        Long time = Math.abs(oneDate.getTime() - twoDate.getTime());
        return time / 1000;
    }

    /**
     * 获取当月的开始时间
     *
     * @param date
     * @return
     */
    public static Date getMonthStartTime(Date date) {
        Calendar dateStart = Calendar.getInstance();
        dateStart.setTime(date);
        // 获取前月的第一天
        dateStart.add(Calendar.MONTH, 0);
        dateStart.set(Calendar.DAY_OF_MONTH, 1);
        dateStart.set(Calendar.HOUR_OF_DAY, 0);
        dateStart.set(Calendar.MINUTE, 0);
        dateStart.set(Calendar.SECOND, 0);
        dateStart.set(Calendar.MILLISECOND, 0);
        return dateStart.getTime();
    }

    /**
     * 获取当月的开始时间
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getMonthStartTime(int year, int month) {
        Calendar dateStart = Calendar.getInstance();
        dateStart.set(Calendar.YEAR, year);
        // 获取前月的第一天
        dateStart.set(Calendar.MONTH, month);
        dateStart.set(Calendar.DAY_OF_MONTH, 1);
        dateStart.set(Calendar.HOUR_OF_DAY, 0);
        dateStart.set(Calendar.MINUTE, 0);
        dateStart.set(Calendar.SECOND, 0);
        dateStart.set(Calendar.MILLISECOND, 0);
        return dateStart.getTime();
    }

    /**
     * 获取当月的结束时间
     *
     * @param date
     * @return
     */
    public static Date getMonthEndTime(Date date) {
        Calendar dateEnd = Calendar.getInstance();
        dateEnd.setTime(date);
        // 获取前月的第一天
        dateEnd.add(Calendar.MONTH, 1);
        dateEnd.set(Calendar.DAY_OF_MONTH, 0);
        dateEnd.set(Calendar.HOUR_OF_DAY, 23);
        dateEnd.set(Calendar.MINUTE, 59);
        dateEnd.set(Calendar.SECOND, 59);
        dateEnd.set(Calendar.MILLISECOND, 999);
        return dateEnd.getTime();
    }

    /**
     * 获取当月的结束时间
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getMonthEndTime(int year, int month) {
        Calendar dateEnd = Calendar.getInstance();
        dateEnd.set(Calendar.YEAR, year);
        // 获取前月的第一天
        dateEnd.set(Calendar.MONTH, month + 1);
        dateEnd.set(Calendar.DAY_OF_MONTH, 0);
        dateEnd.set(Calendar.HOUR_OF_DAY, 23);
        dateEnd.set(Calendar.MINUTE, 59);
        dateEnd.set(Calendar.SECOND, 59);
        dateEnd.set(Calendar.MILLISECOND, 999);
        return dateEnd.getTime();
    }

    /**
     * 取得指定日期N天后的日期
     *
     * @param date
     * @param month
     * @return
     */
    public static Date addMonths(Date date, int month) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        cal.add(Calendar.MONTH, month);

        return cal.getTime();
    }

    /**
     * 取得指定日期N年后的日期
     *
     * @param date
     * @param year
     * @return
     */
    public static Date addYears(Date date, int year) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        cal.add(Calendar.YEAR, year);

        return cal.getTime();
    }



    /**
     * 得到两个时间之前的分钟数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int minsBetween(Date startDate, Date endDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        long minTime = calendar.getTimeInMillis();
        calendar.setTime(endDate);
        long maxTime = calendar.getTimeInMillis();
        long betweenMins = (maxTime - minTime) / (1000 * 60 * 24);
        return Integer.parseInt(String.valueOf(betweenMins));
    }

    /**
     * 判断两个日期相差的时长<br/>
     * 返回 minuend - subtrahend 的差
     *
     * @param subtrahend 减数日期
     * @param minuend    被减数日期
     * @param diffField  相差的选项：相差的天、小时
     * @return 日期差
     */
    public static long diff(Date subtrahend, Date minuend, long diffField) {
        long diff = minuend.getTime() - subtrahend.getTime();
        return diff / diffField;
    }

    /**
     * 获取本周的第一天
     *
     * @return String
     **/
    public static Date getWeekStart() {
        Calendar cal = Calendar.getInstance();
        if (cal.get(Calendar.DAY_OF_WEEK) == 1) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        cal.set(Calendar.DAY_OF_WEEK, 2);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取本周的最后一天
     *
     * @return String
     **/
    public static Date getWeekEnd() {
        Calendar cal = Calendar.getInstance();
        if (cal.get(Calendar.DAY_OF_WEEK) != 1) {
            cal.set(Calendar.DAY_OF_WEEK, 7);
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return cal.getTime();
    }

    /**
     * 获取上周的第一天
     *
     * @return String
     **/
    public static Date getLastWeekStart() {
        Calendar cal = Calendar.getInstance();
        if (cal.get(Calendar.DAY_OF_WEEK) == 1) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        cal.set(Calendar.DAY_OF_WEEK, 2);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.add(Calendar.DAY_OF_MONTH, -7);
        return cal.getTime();
    }

    /**
     * 获取上周周的最后一天
     *
     * @return String
     **/
    public static Date getLastWeekEnd() {
        Calendar cal = Calendar.getInstance();
        if (cal.get(Calendar.DAY_OF_WEEK) != 1) {
            cal.set(Calendar.DAY_OF_WEEK, 7);
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        cal.add(Calendar.DAY_OF_MONTH, -7);
        return cal.getTime();
    }


    /**
     * 获取本年的第一天
     *
     * @return String
     **/
    public static Date getYearStart() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }

    /**
     * 获取本年的最后一天
     *
     * @return String
     **/
    public static Date getYearEnd() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, calendar.getActualMaximum(Calendar.MONTH));
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        calendar.getTime();
        return calendar.getTime();
    }

    /**
     * 获取指定年的第一天
     *
     * @return String
     **/
    public static Date getAssignYearStart(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH, 1);
        cal.set(Calendar.DAY_OF_MONTH, 0);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }

    /**
     * 获取去年的最后一天
     *
     * @return String
     **/
    public static Date getLastYearStart() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -1);
        calendar.set(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取去年的最后一天
     *
     * @return String
     **/
    public static Date getLastYearEnd() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -1);
        calendar.set(Calendar.MONTH, calendar.getActualMaximum(Calendar.MONTH));
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 取得季度第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDateOfSeason(Date date) {
        return getMonthStartTime(getSeasonDate(date)[0]);
    }

    /**
     * 取得季度最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDateOfSeason(Date date) {
        return getMonthEndTime(getSeasonDate(date)[2]);
    }

    /**
     * 取得季度月
     *
     * @param date
     * @return
     */
    public static Date[] getSeasonDate(Date date) {
        Date[] season = new Date[3];

        Calendar c = Calendar.getInstance();
        c.setTime(date);

        int nSeason = getSeason(date);
        if (nSeason == 1) {// 第一季度
            c.set(Calendar.MONTH, Calendar.JANUARY);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.FEBRUARY);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.MARCH);
            season[2] = c.getTime();
        } else if (nSeason == 2) {// 第二季度
            c.set(Calendar.MONTH, Calendar.APRIL);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.MAY);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.JUNE);
            season[2] = c.getTime();
        } else if (nSeason == 3) {// 第三季度
            c.set(Calendar.MONTH, Calendar.JULY);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.AUGUST);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.SEPTEMBER);
            season[2] = c.getTime();
        } else if (nSeason == 4) {// 第四季度
            c.set(Calendar.MONTH, Calendar.OCTOBER);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.NOVEMBER);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.DECEMBER);
            season[2] = c.getTime();
        }
        return season;
    }

    /**
     * 1 第一季度 2 第二季度 3 第三季度 4 第四季度
     *
     * @param date
     * @return
     */
    public static int getSeason(Date date) {

        int season = 0;

        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                season = 1;
                break;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                season = 2;
                break;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                season = 3;
                break;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                season = 4;
                break;
            default:
                break;
        }
        return season;
    }

    /**
     * 时间转化成corn表达式
     * 2020-09-15 11:32:39  ->  39 32 11 15 09 ? 2020
     *
     * @param date
     * @return
     */
    public static String dateToCorn(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(TIME_PATTON_CRON);
        String formatTimeStr = null;
        if (date != null) {
            formatTimeStr = sdf.format(date);
        }
        return formatTimeStr;
    }
    /**
     * 获取今年是哪一年
     * @return
     */
    public static Integer getNowYear() {
        Date date = new Date();
        return getNowYear(date);
    }
    /**
     * 获取今年是哪一年
     * @return
     */
    public static Integer getNowYear(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return Integer.valueOf(gc.get(1));
    }

    /**
     * 获取本年的开始时间
     * @return
     */
    public static Date getBeginDayOfYear() {
        return getBeginDayOfYear(new Date());
    }

    /**
     * 获得time所在年的第一天
     * @param time
     * @return
     */
    public static Date getBeginDayOfYear(Date time){
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        cal.set(Calendar.YEAR, cal.get(Calendar.YEAR));
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);

        return getDayStartTime(cal.getTime());
    }

    /**
     * 获取本年的结束时间
     * @return
     */
    public static Date getEndDayOfYear() {
        return getEndDayOfYear(new Date());
    }


    /**
     * 获取本年的结束时间
     * @return
     */
    public static Date getEndDayOfYear(Date time) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        cal.set(Calendar.YEAR, cal.get(Calendar.YEAR));
        cal.set(Calendar.MONTH, Calendar.DECEMBER);
        cal.set(Calendar.DATE, 31);
        return getDayEndTime(cal.getTime());
    }
    /**
     * 获取某个日期的开始时间
     * @param d
     * @return
     */
    public static Date getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if(null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
//        return new Timestamp(calendar.getTimeInMillis());
        return calendar.getTime();
    }

    /**
     * 获取某个日期的结束时间
     * @param d
     * @return
     */
    public static Date getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if(null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
//        return new Timestamp(calendar.getTimeInMillis());
        return calendar.getTime();
    }



    public static void main(String[] args) {
       /* System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(parseDateTime("2020-02-29 23:59:59")));
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(addYears(parseDateTime("2020-02-29 23:59:59"), -1)));
        Date date = new Date();
        Integer dateYear = getDateYear(date);
        Integer dateMonth = getDateMonth(date);
        int day = getDay(date);
        int hour = getHour(date);
        int minute = getMinute(date);
        int second = getSecond(date);
        System.out.println("年" + dateYear + "月" + dateMonth + "日" + day + "时" + hour + "分" + minute + "秒" + second);
        System.out.println(dateToCorn(new Date()));
        System.out.println(formatTime(new Date()));*/
       /* System.out.println(formatHour(DateUtil.addHour(new Date(), 4)));
        System.out.println(getStartTime(addDays(new Date(), -1)));*/
        Date startDate=DateUtil.parseDate("2022-11-18 00:00:00");
        Date endDate = DateUtil.parseDate("2022-11-19 00:00:00");
        System.out.println(daysBetween(startDate,endDate));
    }
}
